#include "hook.h"

bool m_CachedPtr(void* unity_obj) {
    if (!unity_obj) return false;
#if defined(__aarch64__)
    return (*(uintptr_t*)((uintptr_t)unity_obj + 0x10) != 0);
#else
    return (*(uintptr_t*)((uintptr_t)unity_obj + 0x8) != 0);
#endif
}
bool* (*Object_IsNativeObjectAlive)(void *object);
Transform* (*GetBoneTransform)(Animator*,int);
bool* (*get_isHuman)(Animator*);
Transform* (* GameObject_get_transform)(void* instance);
Transform* (* Component_get_transform)(void* instance);
MonoArray<void**>* (*Object_FindObjectsOfType)(void*);
MonoString* (*Object_get_name)(void*);
void* (*Type_GetTypeName)(MonoString*);
void* (*il2cpp_thread_attach)(void*);
void* (*il2cpp_domain_get)();
Vector3(*Transform_get_position)(void* instance);
Vector3(*Camera_WorldToScreen)(Camera* camera, Vector3 position);
Camera* (*Camera_get_main)();
Vector3 (*get_forward)(void *instance);
void (*set_localScale)(Transform* instance, Vector3 Scale);
bool* (*get_isTrigger)(void* instance);
void initializeFunctionPointers()
{
    void* handle = xdl_open("libil2cpp.so", XDL_DEFAULT);
    while (!handle) {
        handle = xdl_open("libil2cpp.so", XDL_DEFAULT);
        sleep(1);
    }

    get_isTrigger = (bool* (*)(void* instance))GET_METHOD("UnityEngine.PhysicsModule.dll", "UnityEngine", "Collider", "get_isTrigger", 0);
    get_forward = (Vector3 (*)(void*))GET_METHOD("UnityEngine.dll", "UnityEngine", "Transform", "get_forward", 0);
    set_localScale = (void(*)(Transform*,Vector3))GET_METHOD("UnityEngine.dll", "UnityEngine", "Transform", "set_localScale", 1);
    Object_IsNativeObjectAlive = (bool* (*)(void*))GET_METHOD("UnityEngine.dll", "UnityEngine", "Object", "IsNativeObjectAlive", 1);
    GetBoneTransform = (Transform* (*) (Animator*,int))GET_METHOD("UnityEngine.AnimationModule.dll", "UnityEngine", "Animator", "GetBoneTransform", 1);
    get_isHuman = (bool* (*) (Animator*))GET_METHOD("UnityEngine.AnimationModule.dll", "UnityEngine", "Animator", "get_isHuman", 0);
    Camera_WorldToScreen = (Vector3 (*) (Camera* camera,Vector3 Pos))GET_METHOD("UnityEngine.dll", "UnityEngine", "Camera", "WorldToScreenPoint", 1);
    Camera_get_main = (Camera * (*)())GET_METHOD("UnityEngine.dll", "UnityEngine", "Camera", "get_main", 0);
    GameObject_get_transform = (Transform * (*)(void*))GET_METHOD("UnityEngine.dll", "UnityEngine", "GameObject", "get_transform", 0);
    Transform_get_position = (Vector3(*)(void*))GET_METHOD("UnityEngine.dll", "UnityEngine", "Transform", "get_position", 0);
    Component_get_transform = (Transform* (*)(void*))GET_METHOD("UnityEngine.dll", "UnityEngine", "Component", "get_transform", 0);
	Object_FindObjectsOfType = (MonoArray<void**>* (*) (void* Type))GET_METHOD("UnityEngine.dll", "UnityEngine", "Object", "FindObjectsOfType", 1);
	Type_GetTypeName = (void* (*) (MonoString * Name))GET_METHOD("mscorlib.dll", "System", "Type", "GetType", 1);
	Object_get_name = (MonoString* (*) (void* obj))GET_METHOD("UnityEngine.CoreModule.dll", "UnityEngine", "Object", "ToString", 0);
    il2cpp_thread_attach = (void* (*) (void*domain))xdl_sym(handle, "il2cpp_thread_attach", nullptr);
    il2cpp_domain_get = (void* (*)())xdl_sym(handle, "il2cpp_domain_get", nullptr);
}